package com.yanqu.road.web.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.yanqu.road.api.test.TestJob;
import com.yanqu.road.server.command.api.CmdMetaInfo;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.webservice.invoke.GameWebServiceInvoke;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * wmm
 * 2023/2/5
 */

@RestController
@RequestMapping("/api")
public class CmdApiController {

    @ResponseBody
    @RequestMapping(value = "list")
    public String listApi(){
       String result = GameWebServiceInvoke.listCommandApi();

       List<CmdMetaInfo> list = JSON.parseObject(result, new TypeReference<List<CmdMetaInfo>>() {});

       TestJob.setApiList(list);
       return result;
    }

    @ResponseBody
    @RequestMapping(value = "test")
    public Object test(@RequestParam("levelStr") String levelStr,
                       @RequestParam("positionWeight") String positionWeight,
                       @RequestParam("initPositionLevel") int initPositionLevel,
                       @RequestParam("finalLevel") int finalLevel,
                       @RequestParam("doNum") int doNum){

        Random random = new Random();
        //1;1|2;2
        positionWeight = positionWeight.replace(";", "|");
        positionWeight = positionWeight.replace(",", ";");

        levelStr = levelStr.replace(";", "|");
        levelStr = levelStr.replace(",", ";");

        //获取最高总等级
        String[] levelStrArr = levelStr.split("\\|");
        String maxLevelStr = levelStrArr[levelStrArr.length - 1];
        String[] maxLevelStrArr = maxLevelStr.split(";");
        int maxLevel = Integer.parseInt(maxLevelStrArr[0]);

        int allNum = 0;
        for (int i = 0; i < doNum; i++) {
            //位置等级
            Map<Integer, Integer> postionLevelMap = new HashMap<>();
            for (String positionStr : positionWeight.split("\\|")) {
                String[] positionArr = positionStr.split(";");
                //随机出等级
                int level = random.nextInt(maxLevel + 1);
                //获取总等级
                int allLevel = getAllLevel(postionLevelMap);
                if (level > initPositionLevel - allLevel) {
                    level = initPositionLevel - allLevel;
                }
                postionLevelMap.put(Integer.parseInt(positionArr[0]), level);
            }

            //判断最终等级是否合法
            if (finalLevel > maxLevel * postionLevelMap.size() ) {
                return "finalLevel错误";
            }

            int num = 0;
            while (true) {
                num++;
                int level = RandomHelper.getRandomKeyByWeight(levelStr);
                //获取位置
                int position = RandomHelper.getRandomKeyByWeight(positionWeight);
                int currentLevel = postionLevelMap.get(position);
                if (level > currentLevel) {
                    //替换
                    postionLevelMap.put(position, level);
                }
                //判断总等级是否到达
                int allLevel = getAllLevel(postionLevelMap);
                if (allLevel >= finalLevel) {
                    break;
                }
            }
            allNum += num;
        }
        //计算平均值
        return allNum / doNum;
    }

    public static int getAllLevel(Map<Integer, Integer> postionLevelMap) {
        int allLevel = 0;
        for (int leve : postionLevelMap.values()) {
            allLevel += leve;
        }
        return allLevel;
    }

    /**
     * 参数：星宿数量，单个星宿的词条数量，有效门客数量，门客总池（可固定写死10个），属于有效门客的词条数量，（总词条数量 =星宿数量*单个星宿的词条数量）模拟次数1w或者1k都可以
     * 结果需求：当我输入这些参数后，跑多少次才能达到我输入的属于有效门客的词条数量
     * @param levelStr
     * @param positionWeight
     * @param initPositionLevel
     * @param finalLevel
     * @param doNum
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "wingRoomChakraTest")
    public Object test(@RequestParam("positionNum") int positionNum,
                       @RequestParam("positionCtNum") int positionCtNum,
                       @RequestParam("targetPatronsNum") int targetPatronsNum,
                       @RequestParam("patronsNum") int patronsNum,
                       @RequestParam("targetCtNum") int targetCtNum,
                       @RequestParam("doNum") int doNum){
        //星宿位置
        Map<Integer, Set<Integer>> positionMap = new HashMap<>();
        RandomHelper randomHelper = new RandomHelper();
        int allNum = 0;
        for (int i = 0; i < doNum; i++) {
            int num = 0;
            while (true) {
                num++;
                //卜卦
                int position = randomHelper.next(0, positionNum);
                Set<Integer> patronsSet = generateRandomNumbers(positionCtNum, 1, patronsNum);
                positionMap.put(position, patronsSet);
                //计算有效门客的词条数量
                if (countSuccess(positionMap, targetPatronsNum, targetCtNum)) {
                    break;
                }
            }
            allNum += num;
        }
        return allNum / doNum;
    }

    public static boolean countSuccess(Map<Integer, Set<Integer>> positionMap, int targetPatronsNum, int targetNum) {
        int num = 0;
        for (Set<Integer> set : positionMap.values()) {
            for (int patronsId : set) {
                if (targetPatronsNum >= patronsId) {
                    num++;
                }
            }
        }
        if (num >= targetNum) {
            return true;
        }
        return false;
    }

    public static Set<Integer> generateRandomNumbers(int n, int min, int max) {
        if (n > (max - min + 1)) {
            throw new IllegalArgumentException("无法生成 " + n + " 个不同的整数，因为范围不够");
        }
        Random random = new Random();
        Set<Integer> numbers = new HashSet<>();

        while (numbers.size() < n) {
            int randomNumber = random.nextInt(max - min + 1) + min;
            numbers.add(randomNumber);
        }

        return numbers;
    }
}
